"use strict";

exports.__esModule = true;
require("core-js/modules/es.error.cause.js");
function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
var _rowIndexMapper = /*#__PURE__*/new WeakMap();
var _columnIndexMapper = /*#__PURE__*/new WeakMap();
var _CellRangeToRenderableMapper_brand = /*#__PURE__*/new WeakSet();
/* eslint-disable jsdoc/require-description-complete-sentence */
/**
 * CellRangeToRenderableMapper is a utility responsible for converting CellRange instances
 * defined in visual coordinates (which may include hidden rows/columns) into renderable
 * coordinates (excluding hidden indices).
 *
 * This class encapsulates the translation logic, allowing other modules to operate
 * on renderable coordinates without needing to be aware of the underlying index mapping implementation.
 *
 * It promotes separation of concerns by decoupling the transformation logic from data structures
 * like CellRange or CellCoords, keeping those classes clean and focused on structural concerns.
 *
 * Example usage:
 *   import { resolveWithInstance } from './utils/staticRegister';
 *
 *   const cellRange = new CellRange(...);
 *   const renderableRange = resolveWithInstance(this.hot, 'cellRangeMapper')
 *     .toRenderable(cellRange);
 */
class CellRangeToRenderableMapper {
  constructor(_ref) {
    let {
      rowIndexMapper,
      columnIndexMapper
    } = _ref;
    /**
     * Gets nearest coordinates that points to the visible row and column indexes. If there are no visible
     * rows and/or columns the `null` value is returned.
     *
     * @private
     * @param {CellCoords} coords The coords object as starting point for finding the nearest visible coordinates.
     * @param {1|-1} rowSearchDirection The search direction. For value 1, it means searching from top to bottom for
     *                                  rows and from left to right for columns. For -1, it is the other way around.
     * @param {1|-1} columnSearchDirection The same as above but for rows.
     * @returns {CellCoords|null} Visual cell coordinates.
     */
    _classPrivateMethodInitSpec(this, _CellRangeToRenderableMapper_brand);
    /**
     * The instance of the IndexMapper class for row indexes.
     *
     * @param {IndexMapper}
     */
    _classPrivateFieldInitSpec(this, _rowIndexMapper, void 0);
    /**
     * The instance of the IndexMapper class for row indexes.
     *
     * @param {IndexMapper}
     */
    _classPrivateFieldInitSpec(this, _columnIndexMapper, void 0);
    _classPrivateFieldSet(_rowIndexMapper, this, rowIndexMapper);
    _classPrivateFieldSet(_columnIndexMapper, this, columnIndexMapper);
  }

  /**
   * Converts the visual coordinates of the CellRange instance to the renderable coordinates.
   *
   * @param {CellRange} range The CellRange instance with defined visual coordinates.
   * @returns {CellRange | null}
   */
  toRenderable(range) {
    const rowDirection = range.getVerticalDirection() === 'N-S' ? 1 : -1;
    const columnDirection = range.getHorizontalDirection() === 'W-E' ? 1 : -1;
    const from = _assertClassBrand(_CellRangeToRenderableMapper_brand, this, _getNearestNotHiddenCoords).call(this, range.from, rowDirection, columnDirection);
    if (from === null) {
      return null;
    }
    const to = _assertClassBrand(_CellRangeToRenderableMapper_brand, this, _getNearestNotHiddenCoords).call(this, range.to, -rowDirection, -columnDirection);
    if (to === null) {
      return null;
    }
    const newRange = range.clone();
    newRange.from = from;
    newRange.to = to;
    if (!newRange.includes(range.highlight)) {
      newRange.highlight = from;
    }
    return newRange;
  }
}
exports.CellRangeToRenderableMapper = CellRangeToRenderableMapper;
function _getNearestNotHiddenCoords(coords, rowSearchDirection) {
  let columnSearchDirection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : rowSearchDirection;
  const nextVisibleRow = _assertClassBrand(_CellRangeToRenderableMapper_brand, this, _getNearestNotHiddenIndex).call(this, _classPrivateFieldGet(_rowIndexMapper, this), coords.row, rowSearchDirection);
  if (nextVisibleRow === null) {
    return null;
  }
  const nextVisibleColumn = _assertClassBrand(_CellRangeToRenderableMapper_brand, this, _getNearestNotHiddenIndex).call(this, _classPrivateFieldGet(_columnIndexMapper, this), coords.col, columnSearchDirection);
  if (nextVisibleColumn === null) {
    return null;
  }
  return coords.clone().assign({
    row: nextVisibleRow,
    col: nextVisibleColumn
  });
}
/**
 * Gets nearest visual index. If there are no visible rows or columns the `null` value is returned.
 *
 * @private
 * @param {IndexMapper} indexMapper The IndexMapper instance for specific axis.
 * @param {number} visualIndex The index as starting point for finding the nearest visible index.
 * @param {1|-1} searchDirection The search direction. For value 1, it means searching from top to bottom for
 *                               rows and from left to right for columns. For -1, it is the other way around.
 * @returns {number|null} Visual row/column index.
 */
function _getNearestNotHiddenIndex(indexMapper, visualIndex, searchDirection) {
  if (visualIndex < 0) {
    return visualIndex;
  }
  return indexMapper.getNearestNotHiddenIndex(visualIndex, searchDirection);
}